home *** CD-ROM | disk | FTP | other *** search
/ Celestin Apprentice 5 / Apprentice-Release5.iso / Source Code / Libraries / VideoToolbox 96.06.15 / VideoToolboxSources / VideoTFB.c < prev    next >
Text File  |  1994-09-06  |  10KB  |  367 lines

  1. /* VideoTFB.c
  2. VideoTFB.c allows direct control of the original Apple color video cards, which
  3. are no longer sold by Apple but are available for $90 from Shreve Systems
  4. (800-227-3971). The required video card for VideoTFB is called either "Toby
  5. frame buffer card" or "Mac II High-Resolution Video Card". Don’t use these
  6. routines unless you’re prepared to deal with the resulting hardware
  7. dependencies. Try the demo ScrollDemo.
  8.  
  9. Most people should skip this file and go to GDVideo.c instead, since those
  10. routines will work with ALL Mac video cards.
  11.  
  12. TFB stands for "Toby Farrand board". Toby Farrand is the guy at Apple that wrote
  13. the video driver for this card.
  14.  
  15. I wrote this based on my disassembly of the Apple video driver and the memory
  16. diagnostics I received from Toby Farrand.
  17.  
  18. HISTORY:
  19. 10/29/88    dgp    wrote it
  20. 12/5/89        dgp    tidied it up a bit. Deleted two obsolete routines.
  21. 3/20/90        dgp    make compatible with MPW C.
  22. 3/23/90        dgp inserted a test in every routine to exit unless it's a TFB card.
  23. 8/24/91        dgp    Made compatible with THINK C 5.0.
  24. 12/17/92    dgp added cache to speed up TFBInSlot.
  25. 9/5/94 dgp removed assumption in printf's that int==short.
  26. */
  27. #include "VideoToolbox.h"
  28.  
  29. /* The CardBase address depends on which slot the card is plugged into */
  30. /* If the card is plugged into the first slot, i.e. slot 9, then */
  31. /* the address is 0xF9900000. The slots are numbered 9 to F, with addresses */
  32. /* 0xF9900000 to 0xFFF00000. The slot number appears twice in the address */
  33. /* in order to be compatible with Mac II's supporting either 24 or 32 bit */
  34. /* addressing. The macro CARDBASE(slot) generates the proper address. */
  35.  
  36. #define CARDBASE(slot) (unsigned char *)(0xF0000000+0x01100000*slot)
  37. #define VideoBase(slot) (unsigned char *)(0xF0000020+0x01100000*slot)
  38. #define    TFBBase        0x80000
  39. #define TFBPan        0x8000C
  40. #define    TFBIBase    0x8fffc
  41. #define ClutDataReg    0x90018
  42. #define ClutAddrReg    0x9001C
  43. #define    ReadVSync    0xD0000
  44. #define    ReadVInt    0xD0004
  45. #define    ReadIntlc    0xD0008
  46. #define    VIntEnable    0xA0000
  47. #define    VIntDisable    0xA0004
  48. #define GENLOCK        8
  49. #define    GENLOCKREG    1
  50.  
  51. unsigned char TFBRegisterValues[4][16] = {
  52.     {32,71,0,8,30,229,119,70,5,2,2,1,15,65,5,200},            /* 1 bit/pixel */
  53.     {64,71,0,8,60,229,119,70,5,6,6,4,32,4,11,216},            /* 2 bit/pixel */
  54.     {128,71,0,8,120,229,119,70,5,14,14,10,66,-118,22,-24},    /* 4 bit/pixel */
  55.     {0,71,0,8,240,229,119,70,5,30,30,22,134,150,45,249}        /* 8 bit/pixel */
  56. };
  57.  
  58. unsigned char NtscValues[16] =
  59.     {0,183,0,8,96,229,59,25,5,8,26,14,132,14,46,249};        /* from NtscFkey */
  60.  
  61.  
  62. Boolean TFBInSlot(int slot)
  63. {
  64.     GDHandle device;
  65.     static Boolean tested[16]={0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
  66.     static Boolean ok[16];
  67.     
  68.     if(slot>15)return 0;
  69.     if(!tested[slot]){
  70.         tested[slot]=1;
  71.         device=SlotToScreenDevice(slot);
  72.         ok[slot]=EqualString("\p.Display_Video_Apple_TFB",GDName(device),1,1);
  73.     }
  74.     return ok[slot];
  75. }
  76.  
  77. void SetUpTFB(int slot)
  78. {
  79.     register unsigned char *dstPtrB,*srcPtrB;
  80.     register long int i;
  81.  
  82.     if(!TFBInSlot(slot)){
  83.         printf("The card in slot %d is not a TFB card!\n",slot);
  84.         return;
  85.     }
  86.     dstPtrB = CARDBASE(slot) + TFBIBase;
  87.     srcPtrB = &TFBRegisterValues[0][0];
  88.     for (i=15; i>=0; i--) {
  89.         *dstPtrB = ~*srcPtrB++;
  90.         dstPtrB -= 4;
  91.     }
  92. }
  93.  
  94. void RampClutTFB(int slot)
  95. /* loads the clut with an identical linear ramp in R, G, and B. */
  96. {
  97.     register unsigned char *dstPtrB;
  98.     register int i;
  99.  
  100.     if(!TFBInSlot(slot)){
  101.         printf("The card in slot %d is not a TFB card!\n",slot);
  102.         return;
  103.     }
  104.     *(CARDBASE(slot) + ClutAddrReg) = 255;
  105.     dstPtrB = CARDBASE(slot) + ClutDataReg;
  106.     for (i=255; i >= 0; i--){
  107.         *dstPtrB = *dstPtrB = *dstPtrB = (unsigned char) i;
  108.     }
  109.     return;
  110. }
  111.  
  112. void GrayClutTFB(int slot)
  113. /* loads the entire clut with uniform gray. */
  114. {
  115.     register unsigned char *dstPtrB;
  116.     register int i;
  117.  
  118.     if(!TFBInSlot(slot)){
  119.         printf("The card in slot %d is not a TFB card!\n",slot);
  120.         return;
  121.     }
  122.     *(CARDBASE(slot) + ClutAddrReg) = 255;
  123.     dstPtrB = CARDBASE(slot) + ClutDataReg;
  124.     *dstPtrB = *dstPtrB = *dstPtrB = (unsigned char) 255;
  125.     for (i=254; i >= 1; i--){
  126.         *dstPtrB = *dstPtrB = *dstPtrB = (unsigned char) 127;
  127.     }
  128.     *dstPtrB = *dstPtrB = *dstPtrB = (unsigned char) 0;
  129.     return;
  130. }
  131.  
  132. void LoadClutTFB(int slot,unsigned char rgb[256][3])
  133. /* loads the clut with a user-supplied array. */
  134. {
  135.     register unsigned char *srcPtrB,*dstPtrB;
  136.     register int i;
  137.  
  138.  
  139.     if(!TFBInSlot(slot)){
  140.         printf("The card in slot %d is not a TFB card!\n",slot);
  141.         return;
  142.     }
  143.     *(CARDBASE(slot) + ClutAddrReg) = 255;
  144.     dstPtrB = CARDBASE(slot) + ClutDataReg;
  145.     srcPtrB = &rgb[255][2];
  146.     srcPtrB++;
  147.     for (i=255/4; i >= 0; i--){
  148.         *dstPtrB = *(--srcPtrB);
  149.         *dstPtrB = *(--srcPtrB);
  150.         *dstPtrB = *(--srcPtrB);
  151.  
  152.         *dstPtrB = *(--srcPtrB);
  153.         *dstPtrB = *(--srcPtrB);
  154.         *dstPtrB = *(--srcPtrB);
  155.  
  156.         *dstPtrB = *(--srcPtrB);
  157.         *dstPtrB = *(--srcPtrB);
  158.         *dstPtrB = *(--srcPtrB);
  159.  
  160.         *dstPtrB = *(--srcPtrB);
  161.         *dstPtrB = *(--srcPtrB);
  162.         *dstPtrB = *(--srcPtrB);
  163.     }
  164.     return;
  165. }
  166.  
  167. void NewBlankingTFB(int slot)
  168. /* NewBlankingTFB waits for the beginning of the next vertical blanking interval */
  169. /* The standard Apple video rate is 66.67 Hz */
  170. {
  171.     register long *blankingPtr;
  172.  
  173.     if(!TFBInSlot(slot)){
  174.         printf("The card in slot %d is not a TFB card!\n",slot);
  175.         return;
  176.     }
  177.     blankingPtr = (long *) (CARDBASE(slot) + ReadVSync);
  178.     while (*blankingPtr & 1L) ; /* just in case we're in a tight loop, wait for end of blanking */
  179.     while (!(*blankingPtr & 1L)) ; /* wait until beginning of blanking interval */
  180.     return;
  181. }
  182.  
  183. void NewFieldTFB(int slot)
  184. /* NewFieldTFB waits for the beginning of the next video field */
  185. /* The standard Apple video rate is 66.67 Hz */
  186. {
  187.     register long *blankingPtr;
  188.  
  189.     if(!TFBInSlot(slot)){
  190.         printf("The card in slot %d is not a TFB card!\n",slot);
  191.         return;
  192.     }
  193.     blankingPtr = (long *) (CARDBASE(slot) + ReadVSync);
  194.     while (!(*blankingPtr & 1L)) ;    /* wait until beginning of blanking interval */
  195.     while (*blankingPtr & 1L) ;        /* wait for end of blanking */
  196.     return;
  197. }
  198.  
  199. int BlankingTFB(int slot)
  200. /* returns true during the blanking interval */
  201. {
  202.     register long *blankingPtr;
  203.  
  204.     if(!TFBInSlot(slot)){
  205.         printf("The card in slot %d is not a TFB card!\n",slot);
  206.         return 0;
  207.     }
  208.     blankingPtr = (long *) (CARDBASE(slot) + ReadVSync);
  209.     return (int) (*blankingPtr & 1L);
  210. }
  211.  
  212.  
  213. void SetDepthTFB(int slot,short bits)
  214. /* sets up the video card for the desired number of bits/pixel: 1, 2, 4, or 8 */
  215. {
  216.     register unsigned char *dstPtrB, *srcPtrB;
  217.     register long int i;
  218.     short int log2bits;        /* = log2(bits) */
  219.  
  220.     if(!TFBInSlot(slot)){
  221.         printf("The card in slot %d is not a TFB card!\n",slot);
  222.         return;
  223.     }
  224.     if(bits > 8) return;
  225.     log2bits = 0;
  226.     while ( (bits /= 2) > 0 ) log2bits++;
  227.     dstPtrB = (CARDBASE(slot) + TFBBase);
  228.     srcPtrB = &(TFBRegisterValues[log2bits][0]);    
  229.     NewFieldTFB(slot);
  230.     *(dstPtrB + 15*4) = (char) 0xB7;    /* Preload register15. Put the TFB into a reset state */
  231.     /* 0xB7 apparently requests interlace clock off and 0 bits/pixel */
  232.     for(i=15; i>=0; i--) {
  233.         *dstPtrB = ~ *srcPtrB++;
  234.         dstPtrB += 4;
  235.     }
  236.     return;
  237. }
  238.  
  239. void SynchSetDepthTFB(int masterSlot,int slot,short bits)
  240. /* sets up the video card for the desired number of bits/pixel: 1, 2, 4, or 8 */
  241. {
  242.     register unsigned char *dstPtrB, *srcPtrB;
  243.     register long int i;
  244.     short int log2bits;        /* = log2(bits) */
  245.  
  246.     if(!TFBInSlot(slot)){
  247.         printf("The card in slot %d is not a TFB card!\n",slot);
  248.         return;
  249.     }
  250.     if(!TFBInSlot(masterSlot)){
  251.         printf("The card in slot %d is not a TFB card!\n",masterSlot);
  252.         return;
  253.     }
  254.     if(bits!=1 && bits!=2 && bits!=4 && bits!=8){
  255.         printf("SynchSetDepthTFB: %d bits/pixel impossible for a TFB card!\n",(int)bits);
  256.         return;
  257.     }
  258.     log2bits = 0;
  259.     while ( (bits /= 2) > 0 ) log2bits++;
  260.     dstPtrB = (CARDBASE(slot) + TFBBase);
  261.     srcPtrB = &(TFBRegisterValues[log2bits][0]);    
  262.     NewFieldTFB(masterSlot);        /* wait for masterSlot end of frame*/
  263.     *(dstPtrB + 15*4) = (char) 0xB7;    /* Preload register15. Put the TFB into a reset state */
  264.     /* 0xB7 apparently requests interlace clock off and 0 bits/pixel */
  265.     for(i=15; i>=0; i--) {
  266.         *dstPtrB = ~ *srcPtrB++;
  267.         dstPtrB += 4;
  268.     }
  269.     return;
  270. }
  271.  
  272. void SynchToMainDeviceTFB(GDHandle device)
  273. {
  274.     SynchSetDepthTFB(GetDeviceSlot(GetMainDevice()),GetDeviceSlot(device), (**(**device).gdPMap).pixelSize);
  275. }
  276.  
  277. void HaltTFB(int slot)
  278. {
  279.     register unsigned char *dstPtrB;
  280.  
  281.     if(!TFBInSlot(slot)){
  282.         printf("The card in slot %d is not a TFB card!\n",slot);
  283.         return;
  284.     }
  285.     dstPtrB = (CARDBASE(slot) + TFBBase);
  286.     NewFieldTFB(slot);
  287.     *(dstPtrB + 15*4) = (char) 0xB7;    /* Preload register15. Put the TFB into a reset state */
  288.     /* 0xB7 apparently requests interlace clock off and 0 bits/pixel */
  289. }
  290.  
  291. void RestartTFB(int slot,short bits)
  292. {
  293.     register unsigned char *dstPtrB, *srcPtrB;
  294.     register long int i;
  295.     short int log2bits;        /* = log2(bits) */
  296.  
  297.     if(!TFBInSlot(slot)){
  298.         printf("The card in slot %d is not a TFB card!\n",slot);
  299.         return;
  300.     }
  301.     if(bits > 8) return;
  302.     log2bits = 0;
  303.     while ( (bits /= 2) > 0 ) log2bits++;
  304.     dstPtrB = (CARDBASE(slot) + TFBBase);
  305.     srcPtrB = &(TFBRegisterValues[log2bits][0]);    
  306.     *(dstPtrB + 15*4) = (char) 0xB7;    /* Preload register15. Put the TFB into a reset state */
  307.     /* 0xB7 apparently requests interlace clock off and 0 bits/pixel */
  308.     for(i=15; i>=0; i--) {
  309.         *dstPtrB = ~ *srcPtrB++;
  310.         dstPtrB += 4;
  311.     }
  312.     return;
  313. }
  314.  
  315. void HaltDeviceTFB(GDHandle device)
  316. {
  317.     HaltTFB(GetDeviceSlot(device));
  318. }
  319.  
  320. void RestartDeviceTFB(GDHandle device)
  321. {
  322.     RestartTFB(GetDeviceSlot(device), (**(**device).gdPMap).pixelSize);
  323. }
  324.  
  325. void ScrollTFB(int slot,short bits,long x,long y)
  326. {
  327.     register unsigned char *srcPtrB;
  328.     long int s, RowBytes;
  329.  
  330.     if(!TFBInSlot(slot)){
  331.         printf("The card in slot %d is not a TFB card!\n",slot);
  332.         return;
  333.     }
  334.     RowBytes = 1024*bits/8;
  335.     s = 32 + x + RowBytes*y;
  336.     s /= 4;            /* Unfortunately the Base Address is specified in 4 byte words */
  337.     srcPtrB = CARDBASE(slot) + TFBBase;
  338.     *(srcPtrB + 3*4) = ~ s%256;
  339.     s /= 256;
  340.     *(srcPtrB + 2*4) = ~ s%256;
  341. /*
  342.     s /= 256;
  343.     *(srcPtrB + 15*4) = ~ (4*(s%2) + TFBRegisterValues[3][15]);
  344. */
  345. }
  346.  
  347. void PanTFB(int slot,long int x)
  348. /*
  349. PanTFB() pans the display horizontally.
  350. x is the desired starting point in memory, in bytes. 
  351. For simplicity I assume that the vertical scroll is zero.
  352. */
  353. {
  354.     register unsigned char *srcPtrB;
  355.  
  356.     if(!TFBInSlot(slot)){
  357.         printf("The card in slot %d is not a TFB card!\n",slot);
  358.         return;
  359.     }
  360.     x /= 4;            /* Unfortunately the Base Address is specified in 4 byte words */
  361.     x += 8;            /* Apple's origin */
  362.     srcPtrB = CARDBASE(slot) + TFBPan;
  363.     *srcPtrB = ~ x;
  364.     return;
  365. }
  366.  
  367.